#ifndef __SHAPE__ATTRH
#define __SHAPE__ATTRH

/*
 * This file is used to define the Attributes structure that Your Element used.
 * BaseAttr provide the basic OriginPosition item to control.
 * But you can also rewrite a NEW Attr.
 * The only rule is use Coord_t, instead of Pair<> or COORD_t.
 * And also Use String_t instead of std::String to avoid oversize.
 */

// #include "baseactor.h"
#include "string.hpp"
#include <cstdio>
using Action_t = short;
typedef struct _Coord_t
{
    short X;
    short Y;
    int sqaure() { return X * Y; }
    _Coord_t(short x, short y) : X(x), Y(y) {};
    //_Coord_t(int x, int y) : X(short(x)), Y(short(y)) {};
    _Coord_t() {};
    _Coord_t(const _Coord_t& father) : X(father.X), Y(father.Y) {};
    _Coord_t append(short x, short y) const { return _Coord_t{short(this->X + x), short(this->Y + y)}; }
    _Coord_t append(const _Coord_t& b) const { return _Coord_t{short(this->X + b.X), short(this->Y + b.Y)}; }
    bool operator==(const _Coord_t& b) const { return (b.X == X) && (b.Y == Y); }
} Coord_t; // to specify with _COORD(COORD or &PCOORD)
const Coord_t ZERO{0, 0};
const Coord_t ONE{1, 1};
struct CoordGroup
{

    Coord_t pos;
    Coord_t size;
};

struct BaseAttr
{
    Coord_t pos;
    BaseAttr() : pos(-1, -1) {}
    BaseAttr(short x, short y) : pos(x, y) {};
    BaseAttr(Coord_t a) : pos(a) {}
    virtual ~BaseAttr() {}
    // BaseAttr(const Coord_t& a) : pos(a.X, a.Y) {}
};

struct LinePointAttr
{
    LinePointAttr() : beginpos(-1, -1), endpos(-1, -1), drawchar('X') {}
    LinePointAttr(Coord_t begin, Coord_t end, char c) : beginpos(begin), endpos(end), drawchar(c) {}
    ~LinePointAttr() {}
    Coord_t beginpos;
    Coord_t endpos;
    char drawchar{'-'};
};
// NOTICE: Would be Convert into LinePointAttr
struct LineVectorAttr
{
    LineVectorAttr() : beginpos(-1, -1), direction(-1, 1), length(0), drawchar('X') {}
    LineVectorAttr(Coord_t begin, Coord_t end, short len, char c)
        : beginpos(begin), direction(end), length(len), drawchar(c)
    {
    }
    ~LineVectorAttr() {}
    Coord_t beginpos;
    Coord_t direction;
    short length;
    char drawchar{'-'};
};
struct X_lineAttr
{
    X_lineAttr() : beginpos(-1, -1), length(0), drawchar('X') {}
    X_lineAttr(Coord_t pos, short len, char c) : beginpos(pos), length(len), drawchar(c) {}
    ~X_lineAttr() {}
    Coord_t beginpos;
    short length;
    char drawchar{'-'};
};
// Attention:degree range in(-360,360)
struct LineDegreeAttr // TODO: add constructor
{
    Coord_t beginpos;
    float degree;
    short length;
    char drawchar{'-'};
};

struct TextAttr : BaseAttr
{
    TextAttr() : BaseAttr(-1, -1), content("[ERROR]NULLCONTENT"), rendersize(0, 0), rollAllowed(false) {}
    // TextAttr(Coord_t pos, const String_t& con, bool roll)
    //     : BaseAttr(pos), content(con), rendersize(500, 500), rollAllowed(roll)
    // {
    // }
    TextAttr(Coord_t pos, const String_t& con, Coord_t rs, bool roll)
        : BaseAttr(pos), content(con), rendersize(rs), rollAllowed(roll)
    {
    }
    TextAttr(Coord_t pos, const String_t& con, Coord_t rs)
        : BaseAttr(pos), content(con), rendersize(rs), rollAllowed(false)
    {
    }
    ~TextAttr() {}
    String_t content;
    Coord_t rendersize;
    bool rollAllowed{false};
    TextAttr& operator=(TextAttr a)
    {
        pos = a.pos;
        content = a.content;
        rendersize = a.rendersize, rollAllowed = a.rollAllowed;
        return *this;
    }
};
struct ShapeAttr : BaseAttr
{
    ShapeAttr() : BaseAttr(-1, -1), size(0, 0), drawchar('X'), filled(true), offset(0, 0) {}
    ShapeAttr(const Coord_t& where, const Coord_t& howbig, char showwhat, bool isfilled)
        : BaseAttr(where), size(howbig), drawchar(showwhat), filled(isfilled), offset(0, 0)
    {
    }
    ~ShapeAttr() {}
    Coord_t size;
    char drawchar{'X'};
    bool filled{false};
    Coord_t offset;
};
#else
#define WARNING__REDEFINE
#endif